To create a tween media track, you must:
The sample code shown in this section creates a tween sample that interpolates a short integer from 512 to 0. The tween media is attached to the sound track of a QuickTime movie to modify the sound track's volume. The data type for the tween component is kTweenTypeShort.
The sample code shown in Listing 13-1 creates a new track ( t ) to be used as the tween track and new tween media (type TweenMediaType ).
Listing 1 Creating a tween track and tween media
Track t;
Media md;
SampleDescriptionHandle desc;
// ...
// set up the movie, m
// ...
// allocate a sample description handle
desc = (SampleDescriptionHandle)NewHandleClear (
sizeof (SampleDescription));
// create the tween track, t
t = NewMovieTrack (m, 0, 0, kNoVolume);
// create the tween media, md
md = NewTrackMedia (t, TweenMediaType, 600, nil, 0);
(**desc).descSize = sizeof(SampleDescription);
Next, an application must create a tween media sample. The tween media sample is defined as a QT atom container structure that contains one or more kTweenEntry atoms. ( See the chapter "MovieToolBox" for additional information on QT atom containers. ) Each kTweenEntry atom defines a separate tween operation. A single tween sample can describe several parallel tween operations.
The sample code shown in Listing 13-2 creates a new QT atom container and inserts a kTweenEntry atom into the container. Then, it creates two leaf atoms, both children of the kTweenEntry atom. The first leaf atom (atom type kTweenType ) contains the type of the tween data, kTweenTypeShort . The second leaf atom (atom type kTweenData ) contains the two data values for the tween operation, 512 and 0.
Listing 2 Creating a tween sample
QTAtomContainer container = nil;
short tweenDataShort[2];
QTAtomType tweenType;
tweenDataShort[0] = 512;
tweenDataShort[1] = 0;
// create a new atom container to hold the sample
QTNewAtomContainer (&container);
// create the parent tween entry atom
tweenType = kTweenTypeShort;
QTInsertChild (container, kParentAtomIsContainer, kTweenEntry, 1, 0, 0,
nil, &tweenAtom);
// add two child atoms to the tween entry atom
// * the type atom, kTweenType
QTInsertChild (container, tweenAtom, kTweenType, 1, 0,
sizeof(tweenType), &tweenType, nil);
// * the data atom, kTweenData
QTInsertChild (container, tweenAtom, kTweenData, 1, 0, sizeof(short) * 2,
tweenDataShort, nil);
You do not have to start the tween at the beginning of the sample, nor do you have to stop at the end of the sample. You can specify the start of the tween and its duration by adding additional child atoms to the tween entry. You can add a kTweenStartOffset atom to start the tween operation at 500 units into the sample with the following lines of code:
TimeValue time = 500;
QTInsertChild (container, tweenAtom, kTweenStartOffset, 1, 0,
sizeof(TimeValue), &time, nil);
You can specify a duration for the tween operation independent of the sample's duration by adding a kTweenDuration atom to the tween entry, as follows:
TimeValue duration = 1000;
QTInsertChild (container, tweenAtom, kTweenDuration, 1, 0,
sizeof(TimeValue), &duration, nil);
Once the tween samples have been created, you can add them to the tween media and then add the tween media to the track, as shown in Listing 13-3 .
Listing 3 Adding the tween sample to the media and the media to the track
// add the sample to the tween media
BeginMediaEdits (md);
AddMediaSample (md, container, 0,
GetHandleSize(container), kSampleDuration, desc, 1, 0, nil);
EndMediaEdits(md);
// dispose of the sample description handle and the atom container
DisposeHandle ((Handle)desc);
QTDisposeAtomContainer(container);
// add the media to the track
InsertMediaIntoTrack(t, 0, 0, kSampleDuration, kFix1);
Once you have added the tween media to its track, you need to call the AddTrackReference function to create a link between the tween track to the receiving track. AddTrackReference returns the index of the reference it creates.
The sample code shown in Listing 13-4 retrieves the sound track from a movie and calls AddTrackReference to create a link between the tween track ( t ) and the sound track. The reference index is returned in the parameter referenceIndex .
Listing 4 Creating a link between the tween track and the sound track
Track soundTrack;
// retrieve the sound track from the movie
soundTrack = GetMovieIndTrackType (theMovie , 1,
AudioMediaCharacteristic,
movieTrackCharacteristic | movieTrackEnabledOnly);
long referenceIndex;
// create a link between the tween track and the sound track
// on return, referenceIndex contains the index of the link
err = AddTrackReference (soundTrack, t, kTrackModifierReference,
&referenceIndex);
Once you have linked the tween track to its receiving track, you must update the input map of the receiving track's media to indicate how the receiving track should interpret the data it receives from the tween track. To do this, you create a QT atom container and insert an atom of type kTrackModifierInput whose ID is the index returned by the AddTrackReference function. Then, you insert two atoms as children of the kTrackModifierInput atom:
Once you have created the appropriate atoms in the input map, you call SetMediaInputMap to assign the input map to the receiving track's media.
The sample code shown in Listing 13-5 creates an input map for the sound track of a movie. In this code, the tween media is linked to a sound track; the interpolated tween values are used to modify the sound track's volume.
Listing 5 Binding a tween entry to its receiving track
QTAtomContainer inputMap = nil;
// create an atom container to hold the input map
if (QTNewAtomContainer (&inputMap) == noErr)
{
QTAtom inputAtom;
OSType inputType;
long tweenID = 1;
// create a kTrackModifierInput atom
// whose ID is referenceIndex
QTInsertChild(inputMap, kParentAtomIsContainer,
kTrackModifierInput, referenceIndex, 0, 0, nil,
&inputAtom);
// add a child atom of type kTrackModifierTypeVolume
inputType = kTrackModifierTypeVolume;
QTInsertChild (inputMap, inputAtom, kTrackModifierType, 1, 0,
sizeof(inputType), &inputType, nil);
// add a child atom for the ID of the tween to
// modify the volume
QTInsertChild (inputMap, inputAtom, kInputMapSubInputID, 1,
0, sizeof(tweenID), &tweenID, nil);
// assign the input map to the sound media
SetMediaInputMap(GetTrackMedia(soundTrack), inputMap);
// dispose of the input map
QTDisposeAtomContainer(inputMap);
}